package org.mybatis.mapper;

import java.io.InputStreamReader;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.ibatis.io.Resources;
import org.mybatis.core.interfaces.NameGenerator;
import org.mybatis.core.interfaces.impl.DefaultNameGenerator;
import org.mybatis.core.jdbc.SQLStatement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;

public final class GenerateMapperSql
{
  protected static final Logger logger = LoggerFactory.getLogger(GenerateMapperSql.class);
  private NameGenerator columnNameGenerator = new DefaultNameGenerator();
  private String mysql_xml = getXmlFromFile("GenericMapper.txt");

  public void setColumnNameGenerator(NameGenerator columnNameGenerator) {
    this.columnNameGenerator = columnNameGenerator;
  }

  public GenerateMapperSql() {
  }

  public GenerateMapperSql(NameGenerator columnNameGenerator) {
	super();
	this.columnNameGenerator = columnNameGenerator;
}

private Map<String, String> GenEntityReplaceMap(Class<?> clazz)
  {
    SQLStatement sqlStatement = new SQLStatement(clazz, this.columnNameGenerator);
    return sqlStatement.getMybatisMapperSqlMap();
  }

  private String genMapperXml(Class<?> entity, String namespace)
  {
    Map<String,String> parameter = GenEntityReplaceMap(entity);
    parameter.put("namespace", namespace);
    parameter.put("entityName", entity.getName());
    parameter.put("simpleEntityName", entity.getSimpleName());

    String oriXml = this.mysql_xml;

    for (Entry<String,String> entry : parameter.entrySet())
    {
      oriXml = StringUtils.replace(oriXml, "#{" + (String)entry.getKey() + "}", (String)entry.getValue());
    }
    return oriXml;
  }

  public String genMapperXmlFromMapperClass(String className) {
	     try {
	       Class<?> clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
	       Class<?> entity = (Class<?>)((java.lang.reflect.ParameterizedType)clazz.getGenericInterfaces()[0]).getActualTypeArguments()[0];
	       return genMapperXml(entity, className);
	     } catch (Exception e) {
	       logger.error(e.getMessage(), e);
	     }
	     return null;
	   }
  
  public String genMapperXmlFromMapperClass(Class<?> clazz) {
    try {
      Class<?> entity = (Class<?>)((java.lang.reflect.ParameterizedType)clazz.getGenericInterfaces()[0]).getActualTypeArguments()[0];
      return genMapperXml(entity, clazz.getName());
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
    }
    return null;
  }

  private String getXmlFromFile(String file){
	  String xml = null;
	  try {
		xml = FileCopyUtils.copyToString(new InputStreamReader(Resources.getResourceAsStream(file), "UTF-8"));
	} catch (Exception e) {
		e.printStackTrace();
	}
    return xml;
  }
}

